package com.weather.service;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.weather.vo.WeatherResponse;

/**
 * @Description 天气数据接口实现类
 *
 * @author 堆堆堆
 * @date 2018年5月31日 上午11:07:17
 */
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
	private final static Logger logger = LoggerFactory.getLogger(WeatherDataServiceImpl.class);

	// 天气接口地址
	private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?";

	// 超时时间 30 分钟
	private static final long TIME_OUT = 1800L;

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Override
	public WeatherResponse getDataByCityId(String cityId) {

		// 天气接口地址
		String uri = WEATHER_URI + "citykey=" + cityId;
		return this.doGetWeather(uri);
	}

	@Override
	public WeatherResponse getDataByCityName(String cityName) {

		// 天气接口地址
		String uri = WEATHER_URI + "city=" + cityName;
		return this.doGetWeather(uri);
	}

	private WeatherResponse doGetWeather(String uri) {

		// 定义参数
		ObjectMapper mapper = new ObjectMapper();
		WeatherResponse resp = null;
		String strBody = null;
		ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();

		// 判断缓存是否存在，若存在则直接取出
		if (stringRedisTemplate.hasKey(uri)) {
			logger.info("redis has data");

			strBody = ops.get(uri);

		} else {
			logger.info("redis don't has data");

			// 调用接口
			ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);

			// 判断调用结果
			if (respString.getStatusCodeValue() == 200) {
				strBody = respString.getBody();
			}

			// 数据写入缓存 30 分钟
			ops.set(uri, strBody, TIME_OUT, TimeUnit.SECONDS);
		}

		// 把 json 转换为实体
		try {
			resp = mapper.readValue(strBody, WeatherResponse.class);
		} catch (Exception e) {
			logger.error("Error!", e);
		}

		return resp;
	}
}
